package com.charge.util;

import org.apache.commons.lang.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

/**
 * @author:
 * @Description 时间工具类
 * @Date:  2018年2月6日11:17:11
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
	public static final String timeFormatStr = "yyyy-MM-dd HH:mm:ss";
	private static final String dateFormatStr = "yyyy-MM-dd";
	private static final String mimuteFormatStr = "yyyy-MM-dd HH:mm";
	private static final String todayBeginFormatStr = "yyyy-MM-dd 00:00:00";
	private static final String todayEndFormatStr = "yyyy-MM-dd 23:59:59";
	/**
	 * 纯数字、带毫秒的日期格式串
	 */
	private static final String numMillFormatStr = "yyyyMMddHHmmssSSS";
	/**
	 * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String formatDateTime(Date date) {
		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
	}
	/**
	 * yyyy-mm-dd HH:mm:ss格式的日期格式化对象
	 */
	public static final SimpleDateFormat timeFormat = new SimpleDateFormat(
			timeFormatStr);
	/**
	 * yyyy-MM-dd的日期格式化对象
	 */
	public static final SimpleDateFormat dateFormat = new SimpleDateFormat(
			dateFormatStr);
	/**
	 * yyyy-MM-dd HH:mm格式的日期格式化对象
	 */
	public static final SimpleDateFormat minuteFormat = new SimpleDateFormat(
			mimuteFormatStr);
	/**
	 * yyyy-MM-dd 00:00:00的日期格式化对象
	 */
	public static final SimpleDateFormat todayBegin = new SimpleDateFormat(
			todayBeginFormatStr);
	/**
	 * yyyy-MM-dd 23:59:59格式的日期格式化对象
	 */
	public static final SimpleDateFormat todayEnd = new SimpleDateFormat(
			todayEndFormatStr);
	/**
	 * yyyyMMddHHmmssSSS格式的日期格式化对象
	 */
	public static final SimpleDateFormat numMillFormat = new SimpleDateFormat(
			numMillFormatStr);
	static{
		TimeZone zone = TimeZone.getTimeZone("GMT+08:00");
		timeFormat.setTimeZone(zone);
		dateFormat.setTimeZone(zone);
		minuteFormat.setTimeZone(zone);
		todayBegin.setTimeZone(zone);
		todayEnd.setTimeZone(zone);
		numMillFormat.setTimeZone(zone);
	}
	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
		}
		return formatDate;
	}

	/**
	 * 获得当前日期字符串。格式为yyyy-MM-dd
	 * @return
	 */
	public static String currentDate() {
		return dateFormat.format(new Date());
	}
	/**
	 * 获得昨天的日期字符串。格式为yyyy-MM-dd
	 * @return
	 */
	public static String yesterDayDate() {
		return dateFormat.format(addDay(new Date(),-1));
	}
	/**
	 * 获得当前时间字符串。格式为：yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String currentTime() {
		return timeFormat.format(new Date());
	}
	/**
	 * yyyy-MM-dd HH:mm:ss
	 * @return
	 */
    public static String dateToTimeString(Date date){
    	return timeFormat.format(date);
    }
	/**
	 * 获得当前时间字符串，精确到分钟。格式为：yyyy-mm-dd HH:mm
	 * @return
	 */
	public static String currentMinute() {
		return minuteFormat.format(new Date());
	}
	/**
	 * 获得19位长度的时间字符串，格式为：yyyy-MM-dd 00:00:00
	 * @return
	 */
	public static String todayBegin() {
		return todayBegin.format(new Date());
	}
	/**
	 * 获得19位长度的时间字符串，格式为：yyyy-MM-dd 23:59:59
	 * @return
	 */
	public static String todayEnd() {
		return todayEnd.format(new Date());
	}
	
	/**
	 * 获取10位时间，格式为：yyyy-MM-dd
	 */
	public static String getDayStrByDate(Date date){
		return dateFormat.format(date);
	}

	/**
	 * 获取10位时间，格式为：yyyy年MM月dd日
	 */
	public static String getCNDayStrByDate(Date date){
		String str = dateFormat.format(date).replace("-","年").replace("-","月");
		return str + "日";
	}

	/**
	 * 获取19位时间，格式为：yyyy-MM-dd 00:00:00
	 */
	public static String getBeginStrByDate(Date date){
		return todayBegin.format(date);
	}
	
	/**
	 * 获取19位时间，格式为：yyyy-MM-dd 23:59:59
	 */
	public static String getEndStrByDate(Date date){
		return todayEnd.format(date);
	}
	
	/**
	 * 获得精确到毫秒的当前时间字符串。格式为：yyyyMMddHHmmssSSS
	 * @return
	 */
	public static String currentNumMill() {
		return numMillFormat.format(new Date());
	}
	/**
	 * 获得当前时间，格式为yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getNow(){
		return currentTime();
	}
	/**
	 * 把传入的时间增加指定的月份后返回。
	 * @return
	 */
	public static String addMonth(String dateTime,int months,String formatStr){
		if(formatStr==null)
			{formatStr=dateFormatStr;}
		SimpleDateFormat sdf=new SimpleDateFormat(formatStr);
		sdf.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
		try {
			Date d=addMonth(sdf.parse(dateTime),months);
			return sdf.format(d);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 把传入的时间增加指定的小时后返回。
	 * @return
	 */
	public static String addHour(String dateTime,int hours,String formatStr){
		if(formatStr==null)
			{formatStr=dateFormatStr;}
		SimpleDateFormat sdf=new SimpleDateFormat(formatStr);
		try {
			Date d=addHour(sdf.parse(dateTime),hours);
			return sdf.format(d);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 把传入的时间增加指定的分钟后返回。
	 * @return
	 */
	public static String addMinute(String dateTime,int min,String formatStr){
		if(formatStr==null)
			{formatStr=dateFormatStr;}
		SimpleDateFormat sdf=new SimpleDateFormat(formatStr);
		try {
			Date d=addMinute(sdf.parse(dateTime),min);
			return sdf.format(d);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 日期增加小时
	 * @param d
	 * @param hours
	 * @return
	 */
	public static Date addHour(Date d,int hours){
		Calendar cal=Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(d);
		cal.add(Calendar.HOUR,hours);
		return cal.getTime();
	}
	public static Date addMinute(Date d,int min){
		Calendar cal=Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(d);
		cal.add(Calendar.MINUTE,min);
		return cal.getTime();
	}
	/**
	 * 日期增加月份
	 * @param d
	 * @param months
	 * @return
	 */
	public static Date addMonth(Date d,int months){
		Calendar cal=Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(d);
		cal.add(Calendar.MONTH,months);
		return cal.getTime();
	}
	/**
	 * 日期增加天数
	 * @param d
	 * @param days
	 * @return
	 */
	public static Date addDay(Date d,int days){
		Calendar cal=Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(d);
		cal.add(Calendar.DATE,days);
		return cal.getTime();
	}
	/**
	 * 获取的当前时间的Date
	 * @return
	 */
	public static Date getCurrentDate(){
		Calendar cal=Calendar.getInstance(new Locale("zh-CN"));
		return cal.getTime();
	}
	/**
	 * 把传入的时间字符串增加指定天数之后，返回原格式的字符串
	 * @param dateTime
	 * @param days
	 * @param formatStr
	 * @return
	 */
	public static String addDay(String dateTime,int days,String formatStr){
		if(formatStr==null)
			{formatStr=dateFormatStr;}
		SimpleDateFormat sdf=new SimpleDateFormat(formatStr);
		try {
			return sdf.format(addDay(sdf.parse(dateTime),days));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 获取这周的星期日期 add by HYL since 2009-08-07
	 * @param i  星期几?  星期日用0表示
	 * @return
	 */
	public static String getThisWeekDay(int i){
		Calendar cal = Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(new Date());
		cal.add(Calendar.DATE,i+1-cal.get(Calendar.DAY_OF_WEEK));
		return dateFormat.format(cal.getTime());
	}
	/**
	 * 获取上周的星期日期  add by HYL since 2009-08-07
	 * @param i  星期几?  星期日用0表示
	 * @return
	 */
	public static String getLastWeekDay(int i){
		Calendar cal = Calendar.getInstance(new Locale("zh-CN"));
		cal.setTime(new Date());
		cal.add(Calendar.DATE,i-6-cal.get(Calendar.DAY_OF_WEEK));
		return dateFormat.format(cal.getTime());
	}
	/**
	   * 将字符串型的时间转化成Date类型
	   * @param timeStr
	   * @return
	   */
	public static Date stringToDate(String timeStr){
		return StringToDate(timeStr);
	}
	
	   /**
	    * 计算 系统当前时间-输入时间 的时间间隔 单位：小时
	    * @param timeStr
	    * @return
	    */
    public static double disTime(String timeStr){
    	   double d=(stringToDate(getNow()).getTime())-(stringToDate(timeStr).getTime());
		   double dd=d/3600000;
		   return dd;
    }
    /**把时间字符串从一种形式转换成另一种形式*/
    public static String convertTimeFormat(String timeStr,String srcFormatStr,String distFormatStr){
    	SimpleDateFormat srcFormat=new SimpleDateFormat(srcFormatStr);
    	SimpleDateFormat distFormat=new SimpleDateFormat(distFormatStr);
    	srcFormat.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
    	distFormat.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
    	return convertTimeFormat(timeStr, srcFormatStr, distFormatStr);
    }
    /**把时间字符串从一种格式转换成另一种格式*/
    public static String convertTimeFormat(String timeStr,SimpleDateFormat srcFormat,SimpleDateFormat distFormat){
    	if(timeStr==null||timeStr.length()==0)
			{return null;}
    	try {
			return distFormat.format(srcFormat.parse(timeStr));
		} catch (ParseException e) {
			return null;
		}
    }
    /**
     * 获取时间
     * @param elapsedHourValue
     * @return
     */
	public static Date getSubtractedDateByElapsedHourValue(long elapsedHourValue) {
		long elapsedTimeInMillis = elapsedHourValue * 60 * 60 * 1000; 
		long currentTimeInMillis = Calendar.getInstance().getTimeInMillis();

		long previousTimeInMillis = currentTimeInMillis - elapsedTimeInMillis; 
		Date previousDate = new Date(previousTimeInMillis); 
		return previousDate; 
	}

	public static Date getSubtractedDateByElapsedHourValue(int elapsedHourValue) {
		return getSubtractedDateByElapsedHourValue((long)elapsedHourValue); 
	}

	public static Date getSubtractedDateByElapsedHourValue(double elapsedHourValue) {
		long elapsedTimeInMillis = (long)(elapsedHourValue * 60.0 * 60.0 * 1000.0); 
		long currentTimeInMillis = Calendar.getInstance().getTimeInMillis();

		long previousTimeInMillis = currentTimeInMillis - elapsedTimeInMillis; 
		Date previousDate = new Date(previousTimeInMillis); 
		return previousDate; 
	}
	
	public static int getHour() {
		return new GregorianCalendar().get(Calendar.HOUR_OF_DAY);
		//return new GregorianCalendar().get(Calendar.HOUR);
	}
	

	public static int getMinute() {
		return new GregorianCalendar().get(Calendar.MINUTE);
	}
    
	public static void main(String[] args){
		Date lastWeekDay = DateUtils.getSubtractedDateByElapsedHourValue(7*24);
		String lastWeekStr = DateUtils.dateToTimeString(lastWeekDay);
		
		System.out.println(lastWeekStr);
	}
	/**获取时间字符串代表的时间距当前时间的时间间隔单位为：秒*/
	public static long getTimeInterval(String dateStr) {
		Date startTime = null;
		try {
			startTime = timeFormat.parse(dateStr);
		} catch (ParseException e) {
			return -1;
		}
		return (System.currentTimeMillis() - startTime.getTime())/1000;
	}
	
	/**获取时间两个时间字符串之间的时间间隔单位为：秒*/
	public static long getTimeInterval(String startTimeStr,String endTimeStr) {
		Date startTime = null;
		Date endTime = null;
		try {
			startTime = timeFormat.parse(startTimeStr);
			endTime = timeFormat.parse(endTimeStr);
		} catch (ParseException e) {
			return -1;
		}
		return (endTime.getTime() - startTime.getTime())/1000;
	}
	/**
	 * 判断当前时间是否在startTime和endTime之间
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static boolean isBetween(Date startTime,Date endTime) {
		Date now = new Date();
		try {
			if(now.getTime() < startTime.getTime()) {return false;}
			if(now.getTime() > endTime.getTime()) {return false;}
		}catch (Exception e) {
			return false;
		}
		return true;
	}
	/**
	 * 判断当前时间是否在startTime和endTime之间
	 * @param startTimeStr 格式yyyy-MM-dd HH:mm:ss
	 * @param endTimeStr 格式yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static boolean isBetween(String startTimeStr,String endTimeStr) {
		try {
			return isBetween(timeFormat.parse(startTimeStr), timeFormat.parse(endTimeStr));
		} catch (Exception e) {
			return false;
		}
	}
	
	/*
	 * 判断当前日期是否在startDate和endDate之间
	 * @param startDate
	 * @param endDate
	 * @return 如果当然日期小于startDate返回-1，大于endDate返回1，在startDate和endDate之间返回0
	 */
	public static int judgeDate(Date startDate,Date endDate)
	{
		if(startDate==null||endDate==null)
		{
			return -2;
		}
		
		try
		{
			Date now = new Date();
			String endStr=getEndStrByDate(endDate);		//结束时间为yyyy-mm-dd 23:59:59
			
			endDate=timeFormat.parse(endStr);		//转换为时间格式
			
			if(now.getTime()>=startDate.getTime()&&now.getTime()<=endDate.getTime())
			{return 0;}
			else if(now.getTime()<startDate.getTime())
			{return -1;}
			else if(now.getTime()>endDate.getTime())
			{return 1;}
		} catch (Exception e) {
			return -2;
		}
		
		return -2;
	}
	
	public static Date StringToDate(String timeStr)
	{
		if(StringUtil.isNullStr(timeStr))
			{return null;}
		try
		{
			Date date =timeFormat.parse(timeStr);		//转换为时间格式
			
			return date;
		} catch (Exception e) {
			return new Date();
		}
	}

	private static String[] parsePatterns = {
			"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
			"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
			"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

	/**
	 * 日期型字符串转化为日期 格式
	 * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
	 *   "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null){
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}
}
